package modelo;

import geometria.Coordenada;

import java.util.ArrayList;
import java.util.Iterator;



public final class Escenario {

	private Double xMax = 800D;
	private Double yMax = 600D;
	private Double xMin = 0D;
	private Double yMin = 0D;
	//private Long ultimaActualizacion =  new Date().getTime();
	private ArrayList<AeroNave> moviles   = new ArrayList<AeroNave>();
	private ArrayList<Pista>    estaticos = new ArrayList<Pista>();
	
	private static Escenario INSTANCE = null;
	
	private Escenario(){}

	private synchronized static void createInstance() {
		if (INSTANCE == null) { 
	       INSTANCE = new Escenario();
	    }
	}

	public static Escenario getInstance() {
	    if (INSTANCE == null) 
	    	createInstance();
	    return INSTANCE;
	}

	public static void reset(){
		INSTANCE = null;
		
	}
	/**
	 * 	Si recibe una coordenada que se encuentra fuera de los limites del escenario
	 *  devuelve la coordenada correspondiente de a que los limites derecho e izquierdo e inferior y superior fueran adyacentes.
	 *  En otras palabras: cuando te salis del escenario apareces "del otro lado".
	 * 	  @param coordenada a ajustar
	 * 	  @return Devuelve una coordenada ajustada al escenario
	 * 
	 */
	
	public Coordenada ajustarCoordenada(Coordenada c){
		
		Double xFinal = c.getX(); 
		Double yFinal = c.getY();
		
		if (c.getX() > this.xMax)
			xFinal = c.getX() - this.xMax;
		else if(c.getX() < this.xMin)
			xFinal = c.getX() + this.xMax;
		
		if (c.getY() > this.yMax)
			yFinal = c.getY() - this.yMax;
		else if(c.getY() < this.yMin)
			yFinal = c.getY() + this.yMax;
		
		return new Coordenada(xFinal, yFinal);
		
		
		//		Coordenada res = new Coordenada(c.x, c.y);
//		
//		if (res.x > this.xMax) 
//			res.x = res.x - this.xMax;
//		else if(res.x < this.xMin)
//			res.x = res.x + this.xMax;
//		
//		if (res.y > this.yMax) 
//			res.y = res.y - this.yMax;
//		else if(res.y < this.yMin)
//			res.y = res.y + this.yMax;
//		
//		return res;
	}

	public Double getYMax() {
		return yMax;
	}
	public Double getYMin() {
		return yMin;
	}
	public Double getXMax() {
		return xMax;
	}
	public Double getXMin() {
		return xMin;
	}

	public void agregarMovil(AeroNave avion) {
		this.moviles.add(avion);
	}

	public void agregarEstatico(Pista pista) {
		this.estaticos.add(pista);		
	}

	public void actualizar(Double deltaT) {
		Iterator<AeroNave> i = this.moviles.iterator();
		//Long ahora =  new Date().getTime();
		//int FACTOR_DE_AJUSTE = 1000;
		//Double deltaT = (double) (ahora - this.ultimaActualizacion)/FACTOR_DE_AJUSTE;
		while(i.hasNext()){
			// Es probable que aca haya que agregar cosas en el guturo
			AeroNave avion = i.next();
			avion.actualizarPosicion(deltaT);
			//if(avion.intentarAterrizar()){
			//	this.moviles.remove(avion);
			//}
		}
		//TODO : aca debería estar el código que maneja los aterrizajes y (y los choques?)
		//this.ultimaActualizacion = ahora;
	}
	
	public boolean hayColision(){
		Iterator<AeroNave> i = this.moviles.iterator();
		AeroNave nave1,nave2;
		// Recorro todas las naves, y las comparo con todas las otras, para ver si algun par colisiona
		while (i.hasNext()){
			nave1 = i.next();
			Iterator<AeroNave> j = this.moviles.iterator();
			while (j.hasNext()){
				nave2 = j.next();
				if ( nave1.chocoContra(nave2) && (nave1 != nave2) ) return true;
			}
		}
		// Termine de recorrer todo y no hubo colisiones
		return false;
		
	}
}
